# include <bits/stdc++.h>
# define lc (x << 1)
# define rc (x << 1 | 1)
# define mid ((l + r) >> 1)
# define MAXN 100023
using namespace std;
int a[MAXN], n, q, ans[4];
inline int get_num() {
	int k = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if (c == '-') f = -1;
	for(; isdigit(c); c = getchar()) k = k * 10 + c - '0';
	return k * f;
}
struct segtree {
	int mei[4][MAXN << 2];
	void build(int x, int l, int r) {
		if(l == r) {
			mei[a[l]][x] = 1;
		} else {
			build(lc, l, mid);
			build(rc, mid + 1, r);
			for(int i = 1; i <= 3; i++) mei[i][x] = mei[i][lc] + mei[i][rc];
		}
	}
	void query(int x, int l, int r, int s, int t) {
		if(l == s && r == t) {
			for(int i = 1; i <= 3; i++) ans[i] += mei[i][x];
		} else {
			if(t <= mid) query(lc, l, mid, s, t);
			else if(s > mid) query(rc, mid + 1, r, s, t);
			else {
				query(lc, l, mid, s, mid);
				query(rc, mid + 1, r, mid + 1, t);
			}
		}
	}
}T;
int main() {
	freopen("fans.in", "r", stdin);
	freopen("fans.out", "w", stdout);
	n = get_num();
	q = get_num();
	for(int i = 1; i <= n; i++) a[i] = get_num();
	T.build(1, 1, n);
	while(q--) {
		memset(ans, 0, sizeof(ans));
		int l = get_num();
		int r = get_num();
		T.query(1, 1, n, l, r);
		for(int i = 1; i <= 3; i++) printf("%d ", ans[i]);
		printf("\n");
	}
}
